#include "ofxGifRecorder.h"

ofxGifRecorder::ofxGifRecorder()
:m_isRec     (false)
,m_lockRec   (false)
,m_delayTime (0.02)
,m_frameTime (0.00)
{
  auto &events = ofEvents();
  ofAddListener(events.draw, this, &ofxGifRecorder::begin, OF_EVENT_ORDER_BEFORE_APP);
  ofAddListener(events.draw, this, &ofxGifRecorder::end, OF_EVENT_ORDER_AFTER_APP);
  ofAddListener(events.windowResized, this, &ofxGifRecorder::onWindowResize);
  ofAddListener(ofxGifEncoder::OFX_GIF_SAVE_FINISHED, this, &ofxGifRecorder::onGifSaved);
}

ofxGifRecorder::~ofxGifRecorder()
{
  auto &events = ofEvents();
  ofRemoveListener(events.draw, this, &ofxGifRecorder::begin);
  ofRemoveListener(events.draw, this, &ofxGifRecorder::end);
  ofRemoveListener(events.windowResized, this, &ofxGifRecorder::onWindowResize);
  ofRemoveListener(ofxGifEncoder::OFX_GIF_SAVE_FINISHED, this, &ofxGifRecorder::onGifSaved);
}

bool ofxGifRecorder::isRecording()
{
  return m_isRec;
}

bool ofxGifRecorder::isProcessing()
{
  return m_lockRec;
}

void ofxGifRecorder::toggleRecording()
{
  m_isRec ? stopRecording() : startRecording();
}

void ofxGifRecorder::startRecording()
{
  if (m_lockRec) {
    ofLog(OF_LOG_WARNING) << "Can't start a new recording, wait for a previous one to finish...";
    return;
  }
  m_isRec = true;
  m_frame.clear();
  m_frame.allocate(ofGetWidth(), ofGetHeight(), GL_RGBA, 4);
  m_encoder.reset();
  m_encoder.setup(ofGetWidth(), ofGetHeight(), m_delayTime);
  ofLog(OF_LOG_NOTICE) << "Gif recording is started!";
}

void ofxGifRecorder::stopRecording()
{
  m_isRec = false;
  m_lockRec = true;
  m_encoder.save(ofGetTimestampString("Recording from %Y-%m-%d %H:%M:%S")+".gif");
  ofLog(OF_LOG_NOTICE) << "Gif recording is stopped!";
  ofLog(OF_LOG_NOTICE) << "Creating gif file...";
}

void ofxGifRecorder::onGifSaved(string &filename)
{
  m_lockRec = false;
  ofLog(OF_LOG_NOTICE) << "Gif file is created! " << filename;
}

void ofxGifRecorder::begin(ofEventArgs&)
{
  if (!m_isRec) return;

  m_frame.begin();
  ofClear(ofGetBackgroundColor());
}

void ofxGifRecorder::end(ofEventArgs&)
{
  if (!m_isRec) return;

  m_frame.end();

  ofPushStyle();
  ofDisableLighting();
  m_frame.draw(0, 0);
  ofPopStyle();

  m_frameTime += ofGetLastFrameTime();
  if (m_frameTime < m_delayTime) return;

  ofPixels pix;
  m_frame.readToPixels(pix);
  pix.swapRgb();
  m_encoder.addFrame(
    pix.getData(),
    pix.getWidth(),
    pix.getHeight(),
    pix.getBitsPerPixel(),
    m_frameTime
  );

  m_frameTime = 0;
}

void ofxGifRecorder::onWindowResize(ofResizeEventArgs&)
{
  if (!m_isRec) return;

  ofLog(OF_LOG_WARNING) << "Window size has been changed, stopping current recording...";
  stopRecording();
}
